﻿/*
 * Created by: 
 * Created: Monday, February 05, 2007
 */

using System;
using System.Collections;
using System.Collections.Generic;
using Castle.DynamicProxy.Builder.CodeBuilder.SimpleAST;
using Dune.Business.Domain;
using Dune.Business.Domain.Dictionaries;
using Dune.Business.Domain.Users;
using Dune.Common.Utils;
using Dune.DAL.Common;
using Dune.DAL.Managers;
using Iesi.Collections.Generic;
using NHibernate;
using Expression = NHibernate.Expression.Expression;

namespace Dune.DAL.Managers
{
    internal class DictionariesManager : BaseManager, IDictionariesManager
    {
        private ISet<Type> types;


        public DictionariesManager()
        {
            //            types = new SortedSet<Type>();
            types = new HashedSet<Type>();

            types.Add(typeof(User));
            types.Add(typeof(PlaceHolder));
        }



        protected void Check(Type type)
        {
            if (type == null)
                throw new ArgumentException("type");

            if (!types.Contains(type))
                throw new ArgumentException("Type not registred dictionary " + type);
        }

        #region IDictionariesManager Members

        public bool IsDictionary(Type type)
        {
            if (type == null)
                throw new ArgumentException("type");

            return types.Contains(type);
        }

        /// <summary>
        /// return dictionary contents (elements list)
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ICollection GetDictionary(Type type)
        {
            Check(type);
            ICollection ret = null;
            using (IDalOperation op = CreateLoadOperation())
            {
                ICriteria criteria = Session.CreateCriteria(type);
                criteria.SetCacheable(true); // результат зекешируется только если в мапинге класса type присутсвует элемент <cache ... />
                ret = criteria.List();
                op.Commit();
            }
            return ret;
        }

        /// <summary>
        /// generic accessor for method ICollection GetDictionary(Type type)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public ICollection<T> GetDictionary<T>()
        {
            Check(typeof(T));
            return CollectionsUtils.CreateList<T>(GetDictionary(typeof(T)));
        }

        /// <summary>
        /// return element of dictionary
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dictionaryType"></param>
        /// <returns></returns>
        public object GetDictionaryElement(object id, Type dictionaryType)
        {
            Check(dictionaryType);
            object ret = null;
            using (IDalOperation op = CreateLoadOperation())
            {
                ret = Session.Load(dictionaryType, Convert.ToInt32(id));
                op.Commit();
            }

            return ret;
        }


        /// <summary>
        /// generic accessor for method object GetDictionaryElement(object id, Type dictionaryType)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TID"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetDictionaryElement<T, TID>(TID id)
        {
            Check(typeof(T));
            return (T)GetDictionaryElement((object)id, typeof(T));
        }

        #endregion


    }
}